package utils.img;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.awt.image.MemoryImageSource;
import java.awt.image.PixelGrabber;
import java.awt.image.Raster;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;

public class ImageUtil {
	/**
	 *
	 * @param srcImg 源图片
	 * @param tarImg 目标图片
	 * @param x 起始位置
	 * @param y 结束位置
	 * @param w 切割宽度
	 * @param h 切割高度
	 * @throws IOException
	 * 
	 * 切割图片
	 */
	public static BufferedImage ClipImg(BufferedImage srcImg,int x,int y,int w,int h) throws IOException{
		BufferedImage buffImg=srcImg;		
		
		int height=buffImg.getHeight();
		int width=buffImg.getWidth();
		
		if(x>width)x=width;
		if(y>height)x=height;
		
		if((x+w)>width)w=width-x;
		if((y+h)>height)h=height-y;
		
		BufferedImage newImg=buffImg.getSubimage(x, y, w, h);
		
		return newImg;
	}
	public static BufferedImage ClipImg(String srcImg,int x,int y,int w,int h) throws IOException{
		BufferedImage buffImg=ImageIO.read(new File(srcImg));		
		return  ClipImg(buffImg,x,y,w,h);
	}
	
	/**
	 *
	 * @param srcImg
	 * @param tarImg
	 * @param scaleWidth 宽缩放率
	 * @param scaleHeight 高缩放率
	 * @throws IOException
	 *  
	 *  缩放图片
	 */
	
	public static BufferedImage scaleImg(BufferedImage srcImg,double scaleWidth,double scaleHeight) throws IOException{
		BufferedImage buffImg=srcImg;
		double height=buffImg.getHeight()*scaleHeight;
		double width=buffImg.getWidth()*scaleWidth;
		BufferedImage newImg=new BufferedImage((int)width,(int)height,buffImg.getType());
		
		Graphics2D g = newImg.createGraphics();
		
		g.setColor(Color.WHITE); 
		g.fillRect(0, 0, (int)width, (int)height);		
		g.scale(scaleWidth, scaleHeight);		
		
		g.drawImage(buffImg,0,0,null);		
		
		return newImg;
	}
	public static BufferedImage scaleImg(String srcImg,double scaleWidth,double scaleHeight) throws IOException{
		BufferedImage buffImg=ImageIO.read(new File(srcImg));		
		
		return scaleImg(buffImg,scaleWidth,scaleHeight);
	}
	
	/**
	 *
	 * @param srcImg
	 * @param tarImg
	 * @param angle 旋转率
	 * @throws IOException
	 * 
	 * 旋转图片
	 */
	public static BufferedImage roateImg(BufferedImage srcImg,double angle) throws IOException{
		BufferedImage buffImg=srcImg;
		int oldWidth=buffImg.getWidth();
		int oldHeight=buffImg.getHeight();
		
		
		int width=(int)(Math.cos(angle)*oldWidth+Math.sin(angle)*oldHeight);
		int height=(int)(Math.sin(angle)*oldWidth+Math.cos(angle)*oldHeight);
		
		BufferedImage newImg=new BufferedImage(width,height,buffImg.getType());
		
		Graphics2D g = newImg.createGraphics();		

		g.setColor(Color.WHITE); 
		g.fillRect(0, 0,width,height);
		g.translate(width-oldWidth*Math.cos(angle),0);
		g.rotate(angle);
		
		g.drawImage(buffImg,0,0,null);		
		
		return newImg;
	}
	public static BufferedImage roateImg(String srcImg,double angle) throws IOException{
		BufferedImage buffImg=ImageIO.read(new File(srcImg));
		
		return roateImg(buffImg,angle);
	}
	
	/**
	 *
	 * @param srcImg 来源文件
	 * @param text 写入的文本
	 * @param fontHeight 字体大小
	 * @param color 颜色
	 * @param font 字体
	 * @param x 左上角起的左右位置
	 * @param y 左上角起的上下位置
	 * @param alpha 透明度
	 * @throws IOException
	 * 
	 * 写水印
	 */
	public static BufferedImage writeImg(BufferedImage srcImg,String text,int fontHeight,Color color,String font,int x,int y,float alpha) throws IOException{
		BufferedImage buffImg=srcImg;
		Graphics2D g = buffImg.createGraphics();
		
		g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,alpha));
		Font Gfont = new Font(font, Font.PLAIN, fontHeight);
		g.setFont(Gfont);
		g.setColor(color);
		g.drawString(text,x,y);
		
		return buffImg;		
	}
	public static BufferedImage writeImg(String srcImg,String text,int fontHeight,Color color,String font,int x,int y,float alpha) throws IOException{
		BufferedImage buffImg=ImageIO.read(new File(srcImg));
		
		return writeImg(buffImg,text,fontHeight,color,font,x,y,alpha);		
	}
	
	/**
	 * 把图片写入图片
	 * @param srcImg 原图片
	 * @param tarImg 目标图片
	 * @param x 左上角起的左右位置
	 * @param y 左上角起的上下位置
	 * @param alpha alpha 透明度
	 * @return 图片缓冲
	 * @throws IOException
	 */
	public static BufferedImage writeImgToImg(BufferedImage srcImg,BufferedImage tarImg,int x,int y,float alpha) throws IOException{
		BufferedImage buffImg=srcImg;
		Graphics2D g = buffImg.createGraphics();
		
		g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,alpha));

		g.drawImage(tarImg,null,x,y);
		
		return buffImg;		
	}
	/**
	 * 把图片写入图片
	 * @param srcImg 原图片路径
	 * @param tarImg 目标图片路径
	 * @param x 左上角起的左右位置
	 * @param y 左上角起的上下位置
	 * @param alpha alpha 透明度
	 * @return 图片缓冲
	 * @throws IOException
	 */
	public static BufferedImage writeImgToImg(String srcImg,String tarImg,int x,int y,float alpha) throws IOException{
		BufferedImage buffImg=ImageIO.read(new File(srcImg));
		BufferedImage target=ImageIO.read(new File(tarImg));
		
		return writeImgToImg(buffImg,target,x,y,alpha);		
	}
	
	/**
	 * 
	 * @param srcImg 来源文件
	 * @param tarImg 目标文件
	 * @throws IOException 异常
	 * 
	 * 图片滤镜
	 */
	public static BufferedImage filterImg(BufferedImage srcImg,float[] element) throws IOException{
		BufferedImage buffImg=srcImg;
		BufferedImage targetImg=new BufferedImage(buffImg.getWidth(),buffImg.getHeight(),buffImg.getType());		
		
		Kernel kernel=new Kernel(3,3,element);
		ConvolveOp op=new ConvolveOp(kernel);
		
		op.filter(buffImg,targetImg);
		
		return targetImg;
		
	}
	
	public static BufferedImage filterImg(String srcImg,float[] element) throws IOException{
		BufferedImage buffImg=ImageIO.read(new File(srcImg));		
		return filterImg(buffImg,element);
		
	}
	
	public static float[] filter1={
		0.0f,-1.0f,0.0f,
		-1.0f,4f,-1.0f,
		0.0f,-1.0f,0.0f
    };
	public static float[] filter2={
		0.1f,0.1f,0.1f,
		0.1f,0.1f,0.1f,
		0.1f,0.1f,0.1f
    };
	public static float[] filter3={
		-1.0f,0.0f,-1.0f,
		0.0f,4f,0.0f,
		-1.0f,0.0f,-1.0f
    };
	
	
	/**
	 * 把图片缓冲写入文件
	 * @param targetImgName 目标文件
	 * @param imgType 文件类型
	 * @param img 图片缓冲
	 * @throws IOException
	 */
	public static void writeImg(String targetImgName,String imgType,BufferedImage img) throws IOException{
		ImageIO.write(img,imgType,new File(targetImgName));
	}
	
	/**
	 * 灰度化图像，适用于bmp图像。
	 * @param srcImg
	 * @return
	 */
	public static BufferedImage grayImage(BufferedImage srcImg){
		
        Raster imgData=srcImg.getData();
		
		int minX=imgData.getMinX();
		int minY=imgData.getMinY();
		int height=imgData.getHeight();
		int width=imgData.getWidth();
		
		for(int y=minY;y<height;y++){
			
			for(int x=minX;x<width;x++){	
				
				int rgb=srcImg.getRGB(x, y);
				
				Color color=new Color(rgb);  //根据rgb的int值分别取得r,g,b颜色。
				
				int gray=(int)(0.3*color.getRed()+0.59*color.getGreen()+0.11*color.getBlue());
				
				Color newColor=new Color(gray,gray,gray);
				
				srcImg.setRGB(x, y, newColor.getRGB());
				
				}
		}
		
		return srcImg;
	}
	
	/**
	 * 灰度化图像，适用于bmp图像。
	 * @param srcImg
	 * @return
	 * @throws IOException 
	 */
	public static BufferedImage grayImage(String srcImg) throws IOException{
		
		BufferedImage buffImg=ImageIO.read(new File(srcImg));
		
		return grayImage(buffImg);
	}
	
	
	/** 
	 * 二值化图像.
	 * @param srcImg
	 * @return
	 * @throws IOException
	 */
	public static BufferedImage binarizationImage(BufferedImage buffImg) throws IOException{
		
        int average=averageValue(buffImg,false,256);
		
        Raster imgData=buffImg.getData();
		
		int minX=imgData.getMinX();
		int minY=imgData.getMinY();
		int height=imgData.getHeight();
		int width=imgData.getWidth();
		
		for(int y=minY;y<height;y++){
			
			for(int x=minX;x<width;x++){	
				
				int rgb=buffImg.getRGB(x, y);
				
				Color color=new Color(rgb);  //根据rgb的int值分别取得r,g,b颜色。
				
				int value=255-color.getBlue();
				
				if(value>average){
				
					Color newColor=new Color(0,0,0);

					buffImg.setRGB(x, y, newColor.getRGB());
				}
				else
				{
					Color newColor=new Color(255,255,255);

					buffImg.setRGB(x, y, newColor.getRGB());
				}
				
				}
		}
		
		return buffImg;
	}
	/** 
	 * 二值化图像.
	 * @param srcImg
	 * @return
	 * @throws IOException
	 */
	public static BufferedImage binarizationImage(String srcImg) throws IOException{
		BufferedImage buffImg=ImageIO.read(new File(srcImg));
		
		return binarizationImage(buffImg);
	}
	
	/**
	 * 取得平均的灰值数。
	 * @param buffImg
	 * @param above
	 * @param checkPoint
	 * @return
	 */
	private static int averageValue(BufferedImage buffImg,boolean above,int checkPoint){
		int point=0;
		int count=0;
		
		Raster imgData=buffImg.getData();
		
		int minX=imgData.getMinX();
		int minY=imgData.getMinY();
		int height=imgData.getHeight();
		int width=imgData.getWidth();
		
		for(int y=minY;y<height;y++){
			
			for(int x=minX;x<width;x++){	
					
					int rgb=buffImg.getRGB(x, y);
					
					Color color=new Color(rgb);  //根据rgb的int值分别取得r,g,b颜色。
					
					int value=255-color.getBlue();
					
					if(above){
						if(value>checkPoint){
							point++;
							count=count+value;
							}
					}
					else
					{
						if(value<checkPoint){
							point++;
							count=count+value;
							}
					}
					
					}
			}
		 
		 return count/point;
	}
	
	/**
	 * 计算一个点周围点的平均数。
	 * @param buffImg
	 * @param checkPoint
	 * @return
	 * @throws IOException
	 */
	private static int averagePointImage(BufferedImage buffImg,int checkPoint) throws IOException{
		
		int point=0;
		int count=0;
		
		Raster imgData=buffImg.getData();
		
		int minX=imgData.getMinX();
		int minY=imgData.getMinY();
		int height=imgData.getHeight();
		int width=imgData.getWidth();
		
		for(int y=minY+1;y<height-1;y++){
			
			for(int x=minX+1;x<width-1;x++){
				
				Color color1,color2,color3,color4,color5,color6,color7,color8;				
				
				int x1=0,y1=0,x2=0,y2=0,x3=0,y3=0,x4=0,y4=0,x5=0,y5=0,x6=0,y6=0,x7=0,y7=0,x8=0,y8=0;
				
				x1=x-1;y1=y-1;				
				x2=x;y2=y-1;				
				x3=x+1;y3=y-1;
				x4=x-1;y4=y;
				x5=x+1;y5=y;
				x6=x-1;y6=y+1;				
				x7=x;y7=y+1;				
				x8=x+1;y8=y+1;
				
				
				
				color1=new Color(buffImg.getRGB(x1, y1));
				color2=new Color(buffImg.getRGB(x2, y2));
				color3=new Color(buffImg.getRGB(x3, y3));
				color4=new Color(buffImg.getRGB(x4, y4));
				color5=new Color(buffImg.getRGB(x5, y5));
				color6=new Color(buffImg.getRGB(x6, y6));
				color7=new Color(buffImg.getRGB(x7, y7));
				color8=new Color(buffImg.getRGB(x8, y8));
				
				
				if(color1.getBlue()!=checkPoint)count++;
				if(color2.getBlue()!=checkPoint)count++;
				if(color3.getBlue()!=checkPoint)count++;
				if(color4.getBlue()!=checkPoint)count++;
				if(color5.getBlue()!=checkPoint)count++;
				if(color6.getBlue()!=checkPoint)count++;
				if(color7.getBlue()!=checkPoint)count++;
				if(color8.getBlue()!=checkPoint)count++;
				
				point++;
				
				}
		}
		
		return count/point;
	}
	
	/**
	 * 中值滤波1。
	 * @param srcImg
	 * @param checkPoint
	 * @param less
	 * @return
	 * @throws IOException
	 */
	public static BufferedImage medianFilter(BufferedImage buffImg,int checkPoint,boolean less) throws IOException{
		
		int average=averagePointImage(buffImg,checkPoint);
		int count=0;
		
		Raster imgData=buffImg.getData();
		
		int minX=imgData.getMinX();
		int minY=imgData.getMinY();
		int height=imgData.getHeight();
		int width=imgData.getWidth();
		
		for(int y=minY+1;y<height-1;y++){
			
			for(int x=minX+1;x<width-1;x++){
				
				Color color1,color2,color3,color4,color5,color6,color7,color8;				
				
				int x1=0,y1=0,x2=0,y2=0,x3=0,y3=0,x4=0,y4=0,x5=0,y5=0,x6=0,y6=0,x7=0,y7=0,x8=0,y8=0;
				
				x1=x-1;y1=y-1;				
				x2=x;y2=y-1;				
				x3=x+1;y3=y-1;
				x4=x-1;y4=y;
				x5=x+1;y5=y;
				x6=x-1;y6=y+1;				
				x7=x;y7=y+1;				
				x8=x+1;y8=y+1;
				
				color1=new Color(buffImg.getRGB(x1, y1));
				color2=new Color(buffImg.getRGB(x2, y2));
				color3=new Color(buffImg.getRGB(x3, y3));
				color4=new Color(buffImg.getRGB(x4, y4));
				color5=new Color(buffImg.getRGB(x5, y5));
				color6=new Color(buffImg.getRGB(x6, y6));
				color7=new Color(buffImg.getRGB(x7, y7));
				color8=new Color(buffImg.getRGB(x8, y8));
				
				
				if(color1.getBlue()!=checkPoint)count++;
				if(color2.getBlue()!=checkPoint)count++;
				if(color3.getBlue()!=checkPoint)count++;
				if(color4.getBlue()!=checkPoint)count++;
				if(color5.getBlue()!=checkPoint)count++;
				if(color6.getBlue()!=checkPoint)count++;
				if(color7.getBlue()!=checkPoint)count++;
				if(color8.getBlue()!=checkPoint)count++;
				
				if(less&&count<=average)buffImg.setRGB(x, y, new Color(checkPoint,checkPoint,checkPoint).getRGB());
				if(!less&&count>=average)buffImg.setRGB(x, y, new Color(checkPoint,checkPoint,checkPoint).getRGB());
				
				count=0;
				
				}
		}
		
		return buffImg;
	}
	
	/**
	 * 中值滤波1。
	 * @param srcImg
	 * @param checkPoint
	 * @param less
	 * @return
	 * @throws IOException
	 */
	public static BufferedImage medianFilter(String srcImg,int checkPoint,boolean less) throws IOException{
		
		BufferedImage buffImg=ImageIO.read(new File(srcImg));
		
		return medianFilter(buffImg,checkPoint,less);
	}
	
	/**
	 * 中值滤波方法二。
	 * @param srcImg
	 * @return
	 * @throws IOException
	 */
	public static BufferedImage delPoint2(String srcImg) throws IOException{
		
		BufferedImage image=ImageIO.read(new File(srcImg));
		
		int ih,iw;
		int[] pixels;
		
		iw = image.getWidth();   
		ih = image.getHeight();   
		pixels = new int[iw * ih];   
		
		PixelGrabber pg = new PixelGrabber(image.getSource(), 0, 0, iw, ih, pixels, 0, iw);   
		  try {   
		   pg.grabPixels();   
		  } catch (InterruptedException e) {   
		   e.printStackTrace();   
		  }   
		  // 对图像进行中值滤波，Alpha值保持不变   
		  ColorModel cm = ColorModel.getRGBdefault();   
		  for (int i = 1; i < ih - 1; i++) {   
		   for (int j = 1; j < iw - 1; j++) {   
		    int red, green, blue;   
		    int alpha = cm.getAlpha(pixels[i * iw + j]);   
		  
		    // int red2 = cm.getRed(pixels[(i - 1) * iw + j]);   
		    int red4 = cm.getRed(pixels[i * iw + j - 1]);   
		    int red5 = cm.getRed(pixels[i * iw + j]);   
		    int red6 = cm.getRed(pixels[i * iw + j + 1]);   
		    // int red8 = cm.getRed(pixels[(i + 1) * iw + j]);   
		  
		    // 水平方向进行中值滤波   
		    if (red4 >= red5) {   
		     if (red5 >= red6) {   
		      red = red5;   
		     } else {   
		      if (red4 >= red6) {   
		       red = red6;   
		      } else {   
		       red = red4;   
		      }   
		     }   
		    } else {   
		     if (red4 > red6) {   
		      red = red4;   
		     } else {   
		      if (red5 > red6) {   
		       red = red6;   
		      } else {   
		       red = red5;   
		      }   
		     }   
		    }   
		  
		    // int green2 = cm.getGreen(pixels[(i - 1) * iw + j]);   
		    int green4 = cm.getGreen(pixels[i * iw + j - 1]);   
		    int green5 = cm.getGreen(pixels[i * iw + j]);   
		    int green6 = cm.getGreen(pixels[i * iw + j + 1]);   
		    // int green8 = cm.getGreen(pixels[(i + 1) * iw + j]);   
		  
		    // 水平方向进行中值滤波   
		    if (green4 >= green5) {   
		     if (green5 >= green6) {   
		      green = green5;   
		     } else {   
		      if (green4 >= green6) {   
		       green = green6;   
		      } else {   
		       green = green4;   
		      }   
		     }   
		    } else {   
		     if (green4 > green6) {   
		      green = green4;   
		     } else {   
		      if (green5 > green6) {   
		       green = green6;   
		      } else {   
		       green = green5;   
		      }   
		     }   
		    }   
		  
		    // int blue2 = cm.getBlue(pixels[(i - 1) * iw + j]);   
		    int blue4 = cm.getBlue(pixels[i * iw + j - 1]);   
		    int blue5 = cm.getBlue(pixels[i * iw + j]);   
		    int blue6 = cm.getBlue(pixels[i * iw + j + 1]);   
		    // int blue8 = cm.getBlue(pixels[(i + 1) * iw + j]);   
		  
		    // 水平方向进行中值滤波   
		    if (blue4 >= blue5) {   
		     if (blue5 >= blue6) {   
		      blue = blue5;   
		     } else {   
		      if (blue4 >= blue6) {   
		       blue = blue6;   
		      } else {   
		       blue = blue4;   
		      }   
		     }   
		    } else {   
		     if (blue4 > blue6) {   
		      blue = blue4;   
		     } else {   
		      if (blue5 > blue6) {   
		       blue = blue6;   
		      } else {   
		       blue = blue5;   
		      }   
		     }   
		    }   
		    pixels[i * iw + j] = alpha << 24 | red << 16 | green << 8 | blue;   
		   }   
		  }   
		  
		  // 将数组中的象素产生一个图像
		  
		  Image targetImage=Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(iw, ih, pixels, 0, iw));
		  
		  BufferedImage bufferedImage = new BufferedImage(targetImage.getWidth(null), targetImage.getHeight(null),   
	                BufferedImage.TYPE_INT_RGB);   
		  
	      Graphics2D g = bufferedImage.createGraphics();   
	      g.drawImage(targetImage, 0, 0, null);   
	        
	      return bufferedImage;
	}
	
	private static int[][] template1=
	{
			{0,0,0,0,1,0,1,1,1},
			{1,1,1,0,1,0,0,0,0},
			{1,0,0,1,1,0,1,0,0},
			{0,0,1,0,1,1,0,0,1}
			
			};
	
	private static int[][] template2=
	{
			{1,0,1,1,1,1,1,1,1},
			{1,1,1,0,1,1,1,1,1},
			{1,1,1,1,1,1,1,0,1},
			{1,1,1,1,1,0,1,1,1}
			
			};
	
	/**
	 * 细线化图像,使用Hilditch算法.
	 * @param srcImg
	 * @param checkPoint
	 * @param less
	 * @return
	 * @throws IOException
	 */
	public static BufferedImage hilditchImage(BufferedImage buffImg) throws IOException{
		
		List<Point> delPointList=new ArrayList<Point>();
		
		int count=0;
		
		Raster imgData=buffImg.getData();
		
		int minX=imgData.getMinX();
		int minY=imgData.getMinY();
		int height=imgData.getHeight();
		int width=imgData.getWidth();
		
		for(int y=minY+1;y<height-1;y++){
			
			  for(int x=minX+1;x<width-1;x++){
				  
				 Color color=new Color(buffImg.getRGB(x, y));
				 
				 if(color.getBlue()==255)
					 buffImg.setRGB(x,y, new Color(0,0,0).getRGB());
				 else
					 buffImg.setRGB(x,y, new Color(1,1,1).getRGB());
				 
			  }
		}
		
		do{
			
			delPointList.clear();
			
//			int color;
			
//			for(int y=minY+2;y<height-1;y++){
//				
//				  for(int x=minX+1;x<width-2;x++){
//					  
//					  int result=0;
//					  int px,py;
//					  
//					  for(int t=0;t<4;t++){
//						  
//						  int[] tNow=template1[t];
//						  
//						  int tP=0;
//						  
//						  for(int j=0;j<=2;j++){
//							  for(int i=0;i<=2;i++){								
//								  px=x-1+j;
//								  py=y-1+i;
//								  
//								  color=new Color(buffImg.getRGB(px, py)).getBlue();
//								  
//								  result=result+Math.abs(tNow[tP]-color);
//								  
//								  tP++;
//							  }
//						  }
//						  
//						  if(result==0){
//							  buffImg.setRGB(x,y, new Color(0,0,0).getRGB());
//							  break;
//						  }
//						  
//						  result=0;
//					  }
//					  
//					  for(int t=0;t<4;t++){
//						  
//						  int[] tNow=template2[t];
//						  
//						  int tP=0;
//						  
//						  for(int j=0;j<=2;j++){
//							  for(int i=0;i<=2;i++){								
//								  px=x-1+j;
//								  py=y-1+i;
//								  
//								  color=new Color(buffImg.getRGB(px, py)).getBlue();
//								  
//								  result=result+Math.abs(tNow[tP]-color);
//								  
//								  tP++;
//							  }
//						  }
//						  
//						  if(result==0){
//							  
//							  for(int j=0;j<=2;j++){
//								  for(int i=0;i<=2;i++){								
//									  px=x-1+j;
//									  py=y-1+i;
//									  
//									  buffImg.setRGB(px,py, new Color(1,1,1).getRGB());
//								  }
//							  }	
//							  
//							  break;
//							  
//						  }
//						  
//						  
//					  }
//					  
//				  }
//			}
			
		    for(int y=minY+2;y<height-1;y++){
			
			  for(int x=minX+1;x<width-2;x++){				
				
				count=0;
				
				int p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14;				
				
				int x1=0,y1=0,
				    x2=0,y2=0,
				    x3=0,y3=0,
				    x4=0,y4=0,
				    x5=0,y5=0,
				    x6=0,y6=0,
				    x7=0,y7=0,
				    x8=0,y8=0,
				    x9=0,y9=0,
				    x10=0,y10=0,
				    x11=0,y11=0,
				    x12=0,y12=0,
				    x13=0,y13=0,
				    x14=0,y14=0;
				
				x1=x-1;y1=y-1;  //上左				
				x2=x;y2=y-1;	//上中		
				x3=x+1;y3=y-1;  //上右
				
				x4=x-1;y4=y;    //中左
				x5=x+1;y5=y;    //中右
				
				x6=x-1;y6=y+1;	//下左		
				x7=x;y7=y+1;	//下中	
				x8=x+1;y8=y+1;  //下右
				
				x6=x-1;y6=y+1;	//下左		
				x7=x;y7=y+1;	//下中	
				x8=x+1;y8=y+1;  //下右
				
				x9=x-1;y9=y-2;  //上上左				
				x10=x;y10=y-2;	//上上中		
				x11=x+1;y11=y-2;  //上上右
				
				x12=x+2;y12=y-1;  //右右上				
				x13=x+2;y13=y;	//右右中		
				x14=x+2;y14=y+1;  //右右下
				
				p1=new Color(buffImg.getRGB(x1, y1)).getBlue();//上左 p4
				p2=new Color(buffImg.getRGB(x2, y2)).getBlue();//上中	p3	
				p3=new Color(buffImg.getRGB(x3, y3)).getBlue();//上右 p2
				
				p4=new Color(buffImg.getRGB(x4, y4)).getBlue();//中左 p5
				p0=new Color(buffImg.getRGB(x, y)).getBlue();  //中中 p0
				p5=new Color(buffImg.getRGB(x5, y5)).getBlue();//中右 p1
				
				p6=new Color(buffImg.getRGB(x6, y6)).getBlue();//下左 p6
				p7=new Color(buffImg.getRGB(x7, y7)).getBlue();//下中	p7
				p8=new Color(buffImg.getRGB(x8, y8)).getBlue();//下右	p9		
				
				p9=new Color(buffImg.getRGB(x9, y9)).getBlue();//下左 p6
				p10=new Color(buffImg.getRGB(x10, y10)).getBlue();//下中	p7
				p11=new Color(buffImg.getRGB(x11, y11)).getBlue();//下右	p9	
				
				p12=new Color(buffImg.getRGB(x12, y12)).getBlue();//下左 p6
				p13=new Color(buffImg.getRGB(x13, y13)).getBlue();//下中	p7
				p14=new Color(buffImg.getRGB(x14, y14)).getBlue();//下右	p9	
				
				if(p0!=1)
				{
				continue;
				}	
				
				count=p1+p2+p3+p4+p5+p6+p7+p8;
				
				if(!(count>=2 && count<=6))
					continue;
				
				if(((p2==0)&(p3==1)?1:0)
					+((p3==0)&(p5==1)?1:0)
					+((p5==0)&(p8==1)?1:0)
					+((p8==0)&(p7==1)?1:0)
					+((p7==0)&(p6==1)?1:0)
					+((p6==0)&(p4==1)?1:0)
					+((p4==0)&(p1==1)?1:0)
					+((p1==0)&(p2==1)?1:0)!=1)
					continue;
				
				int c2=0;
				
				c2=((p10==0)&(p11==1)?1:0)
				+((p11==0)&(p3==1)?1:0)
				+((p3==0)&(p5==1)?1:0)
				+((p5==0)&(p0==1)?1:0)
				+((p0==0)&(p4==1)?1:0)
				+((p4==0)&(p1==1)?1:0)
				+((p1==0)&(p9==1)?1:0)
				+((p9==0)&(p10==1)?1:0);
				
				if(!((p2*p5*p4==0)||c2!=1))
					continue;
				
				int c5=0;
				
				c5=((p3==0)&(p12==1)?1:0)
				+((p12==0)&(p13==1)?1:0)
				+((p13==0)&(p14==1)?1:0)
				+((p14==0)&(p8==1)?1:0)
				+((p8==0)&(p7==1)?1:0)
				+((p7==0)&(p0==1)?1:0)
				+((p0==0)&(p2==1)?1:0)
				+((p2==0)&(p3==1)?1:0);
				
				if(!((p2*p5*p7==0)||c5!=1))
					continue;
				
				delPointList.add(new Point(x,y));

				}
		  }
		    
		for(Point point:delPointList){
			buffImg.setRGB(point.x,point.y, new Color(0,0,0).getRGB());		    
		    }
		
		}while(!delPointList.isEmpty());		
		
		for(int y=minY+1;y<height-1;y++){
			
			  for(int x=minX+1;x<width-1;x++){
				  
				 Color color=new Color(buffImg.getRGB(x, y));
				 
				 if(color.getBlue()==0)
					 buffImg.setRGB(x,y, new Color(255,255,255).getRGB());
				 else
					 buffImg.setRGB(x,y, new Color(0,0,0).getRGB());
				 
			  }
		}
		
		return buffImg;
	}
	
	/**
	 * 细线化图像,使用Hilditch算法.
	 * @param srcImg
	 * @param checkPoint
	 * @param less
	 * @return
	 * @throws IOException
	 */
	public static BufferedImage hilditchImage(String srcImg) throws IOException{
		
		BufferedImage buffImg=ImageIO.read(new File(srcImg));		
		
		return hilditchImage(buffImg);
	}
	
	/**
	 * 把一张大图像分割成小块。
	 * @param srcImg
	 * @param checkPoint
	 * @return
	 * @throws IOException
	 */
	public static Rectangle[] clipImage(String srcImg,final int checkPoint) throws IOException{
		BufferedImage buffImg=ImageIO.read(new File(srcImg));
		
		List<Integer> xList=new ArrayList<Integer>();
		
		Raster imgData=buffImg.getData();
		int now=0;
		int prev=0;
		
		int minX=imgData.getMinX();
		int minY=imgData.getMinY();
		int height=imgData.getHeight();
		int width=imgData.getWidth();
		
		for(int x=minX;x<width;x++){
			
			  for(int y=minY;y<height;y++){
				  int p0;
					p0=new Color(buffImg.getRGB(x, y)).getBlue();
					if(p0==checkPoint){
						now++;
					}
			  }
			  
			  if((now!=0&&prev==0))xList.add(x);
			  if((now==0&&prev!=0))xList.add(x);
			  
			  prev=now;
			  now=0;
		}
		
		Rectangle[] rectangles=new Rectangle[xList.size()/2];
		Integer[] xPoint=xList.toArray(new Integer[0]);
		
		int t=0;
		for(int i=0;i<xPoint.length;i=i+2){
			rectangles[t++]=new Rectangle(xPoint[i],xPoint[i+1],0,0);
		}	
				
		for(Rectangle rectangle:rectangles){
			now=0;
			prev=0;
			
			for(int y=minY;y<height;y++){
				
				  for(int x=rectangle.getX1();x<rectangle.getX2();x++){
					  int p0;
					  
					  p0=new Color(buffImg.getRGB(x, y)).getBlue();
					  
					  if(p0==checkPoint){
							now++;
						}
				  }
				  
				  if((now!=0&&prev==0))rectangle.setY1(y);
				  if((now==0&&prev!=0))rectangle.setY2(y);
				  
				  prev=now;
				  now=0;
			}
			
		}
		
		return rectangles;
	}
	
	/**
	 * 显示图片中每个颜色点。
	 * @param srcImg
	 * @throws IOException
	 */
	public static void showImg(String srcImg) throws IOException{
		
		BufferedImage buffImg=ImageIO.read(new File(srcImg));
		Raster imgData=buffImg.getData();
		
		int minX=imgData.getMinX();
		int minY=imgData.getMinY();
		int height=imgData.getHeight();
		int width=imgData.getWidth();
		
		for(int y=minY;y<height;y++){
			
			for(int x=minX;x<width;x++){	
				
				int rgb=buffImg.getRGB(x, y);
				
				Color color=new Color(rgb);
				
				System.out.print(" "+color.getRed()+"-"+color.getGreen()+"-"+color.getBlue()+" ");
				
				}
			
			System.out.println();
		}
	}
	
	/**
	 * 反向图片的颜色.
	 * @param srcImg
	 * @return
	 * @throws IOException
	 */
	public static BufferedImage reverseImage(String srcImg) throws IOException{
		BufferedImage buffImg=ImageIO.read(new File(srcImg));
		
		Raster imgData=buffImg.getData();
		
		int minX=imgData.getMinX();
		int minY=imgData.getMinY();
		int height=imgData.getHeight();
		int width=imgData.getWidth();
		
		for(int y=minY;y<height;y++){
			
			for(int x=minX;x<width;x++){				
				
				int rgb=buffImg.getRGB(x, y);
				
				Color color=new Color(rgb);  //根据rgb的int值分别取得r,g,b颜色。
				
				Color newColor=new Color(255-color.getRed(),255-color.getGreen(),255-color.getBlue());
				
				buffImg.setRGB(x, y, newColor.getRGB());
				
				}
		}
		
		return buffImg;
	}
	
	public static void main(String[] args) throws IOException{
		//ClipImg(".\\test.jpg",".\\a.jpg",100,100,60,60);
//		writeImg("./b.jpg","jpg",scaleImg("./a.jpg",0.1,0.1));
        //roateImg(".\\test.jpg",".\\a.jpg",1);
          
//          writeImg(".\\a.jpg","测试",100,Color.BLUE,"宋体",10,200,0.6f);
//		writeImg(".\\target.jpg","jpg",writeImgToImg(".\\a.jpg",".\\b.gif",0,0,0.7f));
		//writeImg(".\\a.jpg","jpg",filterImg(".\\test1.jpg",filter3));
		
//		BufferedImage image=ImageIO.read(new File("5.bmp"));
		
		
//		writeImg("gray.bmp","bmp",image);
		
//		writeImg("blur.bmp","bmp",blurImage("test.bmp"));
		
//		writeImg("gray.bmp","bmp",grayImage("a1.bmp"));
//		
//		writeImg("denoise.bmp","bmp",denoiseImage("gray.bmp"));
//		
//		writeImg("reverse.bmp","bmp",reverseImage("denoise.bmp"));
//		
//		writeImg("nopoint.bmp","bmp",delPoint("reverse.bmp",255,true));
//		
//		writeImg("nopoint1.bmp","bmp",filterImg("nopoint.bmp",filter1));
		
//		writeImg("nopoint1.bmp","bmp",delPoint("nopoint.bmp",255,true));
		
//		showImg("gray.bmp");
		
		//过程灰度化->二值化->中值滤波->细线化。
		
		writeImg("nopoint.bmp","bmp",hilditchImage(medianFilter(binarizationImage(grayImage("genimg.jpg")),255,true)));
		
		int index=0;
		for(Rectangle rectangle:clipImage("nopoint.bmp",0))
			writeImg("nopoint"+(index++)+".bmp","bmp",ClipImg("nopoint.bmp",rectangle.getX1(),rectangle.getY1(),rectangle.getWidth(),rectangle.getHeight()));
		
//		writeImg("line.bmp","bmp",lineImage("denoise.bmp"));
		
	}
}
